﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using Autofac;
using Autofac.Core.Lifetime;
using Autofac.Integration.Mvc;

namespace JiaBao.Core.Infrastructure.DependencyManagement
{
    /// <summary>
    /// 依赖注入管理器
    /// </summary>
    public class ContainerManager
    {
        #region 字段

        private readonly IContainer _container;


        #endregion

        #region 属性

        /// <summary>
        /// 依赖注入基础接口
        /// </summary>
        public virtual IContainer Container
        {
            get { return _container; }
        }
        #endregion

        #region Ctor

        public ContainerManager(IContainer container)
        {
            _container = container;
        }
        #endregion

        #region 内部方法

        #endregion

        #region 解析

        /// <summary>
        /// 解析
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="scope"></param>
        /// <returns></returns>
        public virtual T Resolve<T>(string key = "", ILifetimeScope scope = null) where T : class
        {
            if (scope == null)
                scope = Scope();

            if (string.IsNullOrEmpty(key))
                return scope.Resolve<T>();

            return scope.ResolveKeyed<T>(key);
        }

        /// <summary>
        /// 解析
        /// </summary>
        /// <param name="type"></param>
        /// <param name="scope"></param>
        /// <returns></returns>
        public virtual object Resolve(Type type, ILifetimeScope scope = null)
        {
            if (scope == null)
                scope = Scope();

            return scope.Resolve(type);
        }

        /// <summary>
        /// 解析
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="scope"></param>
        /// <returns></returns>
        public virtual T[] ResolveAll<T>(string key = "", ILifetimeScope scope = null)
        {
            if (scope == null)
                scope = Scope();

            if (string.IsNullOrEmpty(key))
                return scope.Resolve<IEnumerable<T>>().ToArray();

            return scope.ResolveKeyed<IEnumerable<T>>(key).ToArray();
        }

        /// <summary>
        /// 解决未注册服务
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="scope"></param>
        /// <returns></returns>
        public virtual T ResolveUnregistered<T>(ILifetimeScope scope = null) where T : class
        {
            return ResolveUnregistered(typeof(T), scope) as T;
        }

        /// <summary>
        /// 解决未注册服务
        /// </summary>
        /// <param name="type"></param>
        /// <param name="scope"></param>
        /// <returns></returns>
        public virtual object ResolveUnregistered(Type type, ILifetimeScope scope = null)
        {
            if (scope == null)
                scope = Scope();

            var constructors = type.GetConstructors();
            foreach (var constructor in constructors)
            {
                try
                {
                    var parameters = constructor.GetParameters();
                    var parameterInstances = new List<object>();
                    foreach (var parameter in parameters)
                    {
                        var service = Resolve(parameter.ParameterType, scope);
                        if (service == null)
                        {

                     
                            throw new JiaBaoException("未知的依赖注入");
                        }

                        parameterInstances.Add(service);
                    }
                    return Activator.CreateInstance(type, parameterInstances.ToArray());
                }
                catch (Exception)
                {


                }
            }
           
            throw new JiaBaoException("没有找到满足所有依赖关系的构造函数。");
        }

        /// <summary>
        /// 尝试解析
        /// </summary>
        /// <param name="serviceType"></param>
        /// <param name="scope"></param>
        /// <param name="instance">解析结果</param>
        /// <returns>解析成功与否</returns>
        public virtual bool TryResolve(Type serviceType, ILifetimeScope scope, out object instance)
        {
            if (scope == null)
                scope = Scope();

            return scope.TryResolve(serviceType, out instance);
        }

        /// <summary>
        /// 是否为已注册类型
        /// </summary>
        /// <param name="serviceType"></param>
        /// <param name="scope"></param>
        /// <returns></returns>
        public virtual bool IsRegistered(Type serviceType ,ILifetimeScope scope)
        {
            if (scope == null)
                scope = Scope();

            return scope.IsRegistered(serviceType);
        }


        public virtual object ResolveOptional(Type serviceType ,ILifetimeScope scope)
        {
            if (scope == null)
                scope = Scope();

            return scope.ResolveOptional(serviceType);
        }



        #endregion

        /// <summary>
        /// 获取当前()
        /// </summary>
        /// <returns></returns>
        public virtual ILifetimeScope Scope()
        {
            try
            {
                if (HttpContext.Current != null)
                    return AutofacDependencyResolver.Current.RequestLifetimeScope;

                return Container.BeginLifetimeScope(MatchingScopeLifetimeTags.RequestLifetimeScopeTag);
            }
            catch (Exception)
            {
                return Container.BeginLifetimeScope(MatchingScopeLifetimeTags.RequestLifetimeScopeTag);
            }
        }
    }
}
